<?php
class Moobuild {
	private $lastUpdate;
	private $revision;
	private $files;
	private $compressions;
	private $js;

	private $comps = array();
	private $added = array();

	const INI_FILE = 'moobuild.ini';
	const UPDATE_INTERVAL = 3600;

	public function __construct() {
		require_once('javascript.php');
		$this->readIni();
		if($this->lastUpdate < time() - self::UPDATE_INTERVAL){
			$this->update();
		}
		$this->js = new Javascript();
		$this->readPath();
		$this->readJSON();
		$this->js->addSource("if(window.console) console.log('Mootools, rev{$this->revision}');");
	}

	private function readIni(){
		if(file_exists(self::INI_FILE)){
			$file = explode('|', file_get_contents(self::INI_FILE));
			$this->lastUpdate = $file[0];
			$this->revision = $file[1];
		}else{
			$this->lastUpdate = 0;
			$this->revision = 0;
		}
	}

	private function writeIni(){
		file_put_contents(self::INI_FILE, "{$this->lastUpdate}|{$this->revision}");
	}

	private function readPath(){
		$parts = explode('/', $_SERVER['PATH_INFO']);
		$this->files = array();
		if(isset($parts[1]) && strlen($parts[1]) > 0){
			$this->files = explode(',', $parts[1]);
		}
		$this->compressions = array();
		if(isset($parts[2])){
			$this->compressions = explode(',', $parts[2]);
		}
	}

	private function readJSON(){
		$json = file_get_contents('mootools/scripts.json');
		$scripts = json_decode($json);
		foreach($scripts as $dir => $comps) {
			foreach($comps as $name => $details) {
				$this->comps[$name] = array(
					'dir'	=> $dir,
					'deps' => $details->deps
				);
			}
		}
	}

	public function build() {
		$this->addComponents($this->files);
		$js = $this->js;
		foreach($this->compressions as $compression){
			switch ($compression) {
				case 'min':
					$js->min();
					break;
				case 'pack':
					$js->pack();
					break;
				case 'rhino':
					$js->rhino();
					break;
			}
		}
		return $js;
	}

	private function update() {
		$out = exec('svn up mootools', $output, $returnValue);
		if($returnValue !== 0){
			var_dump($output);
			trigger_error('SVN returned non 0 return code: ' . $returnValue . 'msg: ' . $ret);
		}
		preg_match('/ (\d+)\.$/', $out, $rev);
		file_put_contents(self::INI_FILE, time() . "|$rev[1]");
	}

	public function addComponent($name){
		if(in_array($name, $this->added)) return; // already added
		if(array_key_exists($name, $this->comps)){
			$this->added[] = $name;
			$this->addComponents($this->comps[$name]['deps']);
			$this->js->addFile('mootools/' . $this->comps[$name]['dir'].'/'.$name.'.js');
		}else{
			$this->js->addComment("not found: $name\n");
		}
	}

	private function addComponents($names){
		foreach($names as $name) {
			if($name == 'all'){
				foreach ($this->comps as $name => $val) {
					$this->addComponent($name);
				}
			}else{
				$this->addComponent($name);
			}
		}
	}
}
?>